home *** CD-ROM | disk | FTP | other *** search
- ## -*-Tcl-*-
- # ###################################################################
- # AlphaTcl - core Tcl engine
- #
- # FILE: "procUtils.tcl"
- # created: 2/8/97 {6:18:16 pm}
- # last update: 12/05/2000 {09:19:12 AM}
- # Author: Vince Darley
- # E-mail: <vince@santafe.edu>
- # mail: 317 Paseo de Peralta
- # Santa Fe, NM 87501, USA
- # www: <http://www.santafe.edu/~vince/>
- #
- # Copyright (c) 1997-1998 Vince Darley, all rights reserved
- #
- # ###################################################################
- ##
-
- namespace eval procs {}
-
- if {[info tclversion] < 8.0} {
- proc procs::pick {{try_sel 0}} {
- if {$try_sel && [llength [winNames]] && \
- [string length [set sel [getSelect]]]} {
- if {[info procs $sel] == "$sel"} {
- return $sel
- } else {
- return [procs::pick_list $sel]
- }
- } else {
- return [procs::pick_list]
- }
- }
- proc procs::pick_list {{sel ""}} {
- set list [lsort -ignore [info procs]]
- if {[string length $list] > 30000} {
- set len [llength $list]
- set len [expr {$len / 2}]
- set list1 [lrange $list 0 $len]
- lappend list1 "Next Page "
- set list2 {{Previous Page }}
- eval lappend list2 [lrange $list [expr {$len + 1}] end]
- } else {
- set list1 $list
- }
- set tmpList $list1
- while {1} {
- if {[string length $sel] == 0} {
- set name [listpick -p {Func Name:} $tmpList]
- } else {
- set name [listpick -L $sel -p {Func Name:} $tmpList]
- }
- if {$name == "Next Page "} {
- set tmpList $list2
- } elseif {$name == "Previous Page "} {
- set tmpList $list1
-
- } else {
- return $name
- }
- }
- }
- } else {
- ##
- # -------------------------------------------------------------------------
- #
- # "procs::pick" --
- #
- # -------------------------------------------------------------------------
- ##
- proc procs::pick {{try_sel 0}} {
- if {$try_sel && [llength [winNames]] && [string length [set sel [getSelect]]]} {
- if {[llength [uplevel \#0 [list info commands $sel]]] && ![catch {info args $sel}]} {
- return $sel
- }
- } else {
- set sel ""
- }
- set ns ::
- while {1} {
- set procs [lsort -ignore [namespace children $ns]]
- eval lappend procs [lsort -ignore [uplevel \#0 namespace eval $ns [list info procs]]]
- set choice [listpick -L $sel -p "Pick a function or child namespace in '$ns'" $procs]
- if {![regexp {^::} $choice]} {
- if {${ns} == "::"} {
- return "::${choice}"
- } else {
- return "${ns}::${choice}"
- }
- }
- set ns $choice
- }
- }
- }
-
- proc procs::debug {func {line 0}} {
- new -n "* Debug of $func *" -m Tcl -text \
- "# Edit the proc in place. Use:\r# 'Reload Proc'\
- to activate changes\r# 'Apply Changes' to put these changes into the original file\
- \r[procs::generate $func]" \
- -dirty 0
- if {$line > 0} {
- # Add one for the comment we inserted
- incr line 3
- goto [rowColToPos $line 0]
- select [getPos] [nextLineStart [getPos]]
- }
- }
-
- proc procs::patchOriginalsFromFile {f {alerts 1} {keepwin ""}} {
- set openWins [winNames -f]
- # get fixed procs
- uplevel \#0 [list source $f]
- # use 'c' to store comments before each proc
- set procs [procs::listInFile $f c]
- # replace all Alpha's originals
- foreach p $procs {
- if {[catch {procs::autoReplace $p 0 1 c}]} {
- # should not happen
- lappend failed $p
- }
- }
- set nowOpen [winNames -f]
- foreach f [lremove -l $nowOpen $openWins] {
- if {$f != $keepwin} {
- bringToFront $f
- goto [minPos]
- killWindow
- }
- }
- if {[info exists failed]} {
- userMessage $alerts "Couldn't find: $failed, this is BAD."
- }
- userMessage $alerts "Replaced [llength $procs] procs successfully."
- }
-
- proc procs::listInFile {f {comments ""}} {
- if {$comments != ""} { upvar $comments c }
- # open the window
- file::openQuietly $f
- # get procs in order
- set pos [minPos]
- set markExpr "^\[ \t\]*proc"
- set procs ""
- while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
- set start [lindex $res 0]
- set end [nextLineStart $start]
- set text [lindex [getText $start $end] 1]
- set pos $end
- lappend procs $text
- set c($text) [getText [procs::getCommentPos $start] $start]
- }
- killWindow
- return $procs
- }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "procs::getCommentPos" --
- #
- # 'p' should be the start of a proc. This looks for a comment which
- # precedes that procedure. It returns the start of such a comment,
- # or 'p' if none was found. Blank lines are not allowed.
- # -------------------------------------------------------------------------
- ##
- proc procs::getCommentPos {p} {
- set q [prevLineStart $p]
- while {[pos::compare $p > [minPos]]} {
- set pp [lindex [search -n -s -f 1 -m 0 -r 1 -l $p -- "\[ \t\]*#" $q] 0]
- if {$pp == "" || ([pos::compare $pp != $q])} {
- break
- }
- set p $q
- set q [prevLineStart $q]
- }
- return $p
- }
-
- proc procs::generate {p} {
- set a "proc $p \{"
- foreach arg [info args $p] {
- if {[info default $p $arg v]} {
- append a "\{[list $arg $v]\} "
- } else {
- append a "$arg "
- }
- }
- set a [string trimright $a]
- append a "\} \{"
- append a [info body $p]
- append a "\}"
- global tcl_platform
- if {$tcl_platform(platform) == "macintosh"} {
- regsub -all "\n" $a "\r" a
- }
- return $a
- }
-
- proc procs::searchFor {p} {
- set f [procs::find $p]
- if {![string length $f]} {
- global TclmodeVars
- set pwd [pwd]
- if {[info exists TclmodeVars(procSearchPath)]} {
- foreach dir $TclmodeVars(procSearchPath) {
- cd $dir
- set names [grepnames "^\[ \t\]*;?proc [quote::Regfind $p]\[ \t\]" *]
- if {[llength $names]} {
- cd $pwd
- return [lindex $names 0]
- }
- }
- }
- }
- return $f
- }
-
- proc procs::autoReplace {p {ask 1} {addAfterLast 0} {commentArrayVar ""}} {
- set f [procs::searchFor $p]
-
- if {$f == ""} { set f [win::Current] }
-
- if {$commentArrayVar != ""} { upvar $commentArrayVar c }
- if {[info exists c($p)]} {
- set com $c($p)
- } else {
- set com ""
- }
-
- procs::replace $f $p $ask $addAfterLast $com
-
- if {[winDirty]} {
- saveUnmodified
- }
- }
-
- proc procs::replace {f p {ask 1} {addAfterLast 0} {commenttext ""}} {
- file::openQuietly $f
- if {[info tclversion] < 8.0} {
- # Alpha can't cope with colons in names
- regsub -all "\\.\\." $p "::" p
- }
-
- if {[string length $commenttext]} {
- set newp "$commenttext[procs::generate $p]"
- } else {
- set newp [procs::generate $p]
- }
- if {[catch {set a [search -s -f 1 -r 1 -m 0 \
- "^\[ \t\]*proc\[ \t\]+[quote::Regfind $p]\[ \t\]" [minPos]]}]} {
- if {!$addAfterLast} {
- if {$ask} {
- alertnote "Failed to find proc"
- }
- error "Failed to find proc"
- } else {
- # we just add it after the last one
- insertText "\r" $newp "\r\r"
- return
- }
- }
- goto [lindex $a 0]
- set entire [procs::findEnclosing [lindex $a 1]]
- if {[string length $commenttext]} {
- set entire [list [procs::getCommentPos [lindex $entire 0]] [lindex $entire 1]]
- }
- eval select $entire
- if {$newp == [getSelect]} {
- message "No change"
- return
- }
- if {$ask} {
- if {![dialog::yesno "Replace this proc?"]} {
- error "Cancelled"
- }
- }
- eval replaceText $entire [list $newp]
- }
-
- # If the first brace after 'proc' ends the current line, then
- # assume the argument was a single arg with no braces.
- proc procs::findEnclosing {pos {type "proc"} {detailed 0} {may_move 0}} {
- set start [lindex [search -s -m 0 -r 1 -f 0 "^\[ \t\]*;?($type) " $pos] 0]
-
- lappend res $start
-
- # find the parameter block
- set p1 [lindex [search -s -f 1 "\{" $start] 0]
- set p [matchIt "\{" [pos::math $p1 + 1]]
- if {$detailed} {lappend res $p1 $p}
- if {[string trim [getText $p1 [nextLineStart $p1]]] == "\{"} {
- if {[pos::compare $p < $pos]} {
- error "couldn't get proc"
- } else {
- return [list $start [pos::math $p + 1]]
- }
- }
- # find the body
- set p [lindex [search -s -f 1 "\{" $p] 0]
- if {$detailed} {lappend res $p}
- # this should not fail.
- set p [matchIt "\{" [pos::math $p + 1]]
- set p [pos::math $p + 1]
- if {[pos::compare $p < $pos] } { error "couldn't get proc" }
- lappend res $p
- return $res
- }
-
- proc procs::findEnclosingName {pos} {
- set p [lindex [procs::findEnclosing $pos] 0]
- regsub -all "\[ \t\]+" [string trim [getText $p [nextLineStart $p]] "\{ \t\n\r"] " " t
- return [lindex [split $t] 1]
- }
-
-
-
-
-
-
-
-
-
-
-